package org.xxpay.pay.channel.atoa;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import org.springframework.stereotype.Service;
import org.xxpay.common.http.HttpRequestTemplate;
import org.xxpay.common.util.sign.SignUtils;
import org.xxpay.common.util.str.StringUtils;
import org.xxpay.core.common.constant.PayConstant;
import org.xxpay.core.entity.PayOrder;
import org.xxpay.pay.channel.BasePayment;

import java.util.Map;

@Service
public class AtoaPaymentService extends BasePayment {
    private final static String logPrefix = "【AtoA】";
    @Override
    public String getChannelName() {
        return AtoaPayConfig.CHANNEL_NAME;
    }

    /**
     * 支付下单
     * @param payOrder
     * @return
     */
    @Override
    public JSONObject pay(PayOrder payOrder) {
        return doOrderReq(payOrder);
    }
    /**
     * 查询订单
     * @param payOrder
     * @return
     */
    @Override
    public JSONObject query(PayOrder payOrder){
        AtoaPayConfig config = new AtoaPayConfig(getPayParam(payOrder));
        String payOrderId = payOrder.getPayOrderId();
        _log.info("{}开始查询通道订单,payOrderId={}", logPrefix, payOrderId);
        Map<String, Object> params = Maps.newHashMap();
        params.put("mchId", config.getMchId());
        params.put("appId", config.getAppId());
        params.put("mchOrderNo", payOrder.getPayOrderId());
        params.put("sign", getSign(params, config.getPrivateKey()));
        _log.info("{}订单查询请求数据:{}", getChannelName(), JSON.toJSONString(params));
        HttpRequestTemplate requestTemplate = new HttpRequestTemplate(null);
        JSONObject origin = requestTemplate.postForObject(config.getRequestUrl()+ AtoaPayConfig.REQ_PAY_QUERY_URL_FIXX, params, JSONObject.class);
        _log.info("{}响应数据:{}", getChannelName(), JSON.toJSONString(origin));
        // 响应对象
        JSONObject retObj = new JSONObject();
        if(StringUtils.equals("SUCCESS",origin.getString("retCode"))){
            retObj.put("status",origin.getIntValue("status"));
            retObj.put(PayConstant.RETURN_PARAM_RETCODE, PayConstant.RETURN_VALUE_SUCCESS);
            retObj.put("channelOrderNo", origin.getString("channelOrderNo"));
            retObj.put("channelObj", origin);
            return retObj;
        }
        retObj.put(PayConstant.RETURN_PARAM_RETCODE, PayConstant.RETURN_VALUE_FAIL);
        retObj.put(PayConstant.RESULT_PARAM_ERRDES, origin.getString("retMsg"));
        return retObj;
    }
    //下单具体实现
    private JSONObject doOrderReq(PayOrder payOrder){
        AtoaPayConfig config = new AtoaPayConfig(getPayParam(payOrder));
        Map<String,Object> parameters = Maps.newHashMap();
        //设置参数
        setParams(payOrder,config,parameters);
        _log.info("{}请求数据:{}", getChannelName(), JSON.toJSONString(parameters));
        //将订单改为支付中
        rpcCommonService.rpcPayOrderService.updateStatus4Ing(payOrder.getPayOrderId(), null);
        HttpRequestTemplate requestTemplate = new HttpRequestTemplate(null);
        JSONObject origin = requestTemplate.postForObject(config.getRequestUrl()+ AtoaPayConfig.REQ_PAY_URL_FIXX, parameters, JSONObject.class);
        _log.info("{}响应数据:{}", getChannelName(), JSON.toJSONString(origin));
        // 响应对象
        JSONObject retObj = new JSONObject();
        if(StringUtils.equals("SUCCESS",origin.getString("retCode"))){
            JSONObject payParams = origin.getJSONObject("payParams");
            if(StringUtils.equals(config.getExtInfo(),"1")){
                JSONObject rspData = origin.getJSONObject("rspData");
                return  buildPayResultOfForm(retObj, payOrder,"<script type=\"text/javascript\">\n" +
                        "　　window.location.href=\""+ payParams.getString("codeUrl")+"\";\n" +
                        "　　</script>" );
            }
            if(StringUtils.equals("formJump",payParams.getString("payMethod"))){
                return buildPayResultOfForm(retObj,payOrder,payParams.getString("payUrl"));
            }else{
                return buildPayResultOfCodeURL(retObj, payOrder, payParams.getString("codeUrl"));
            }
        }
        retObj.put(PayConstant.RETURN_PARAM_RETCODE, PayConstant.RETURN_VALUE_FAIL);
        retObj.put(PayConstant.RESULT_PARAM_ERRDES, origin.toJSONString());
        return retObj;
    }

    //设置下单请求参数
    private void setParams(PayOrder payOrder, AtoaPayConfig config, Map<String,Object> params){

        params.put("mchId", config.getMchId());
        params.put("appId", config.getAppId());
        params.put("productId", config.getPayMode());
        params.put("mchOrderNo", payOrder.getPayOrderId());
        params.put("currency","cny");
        params.put("amount", payOrder.getAmount());
        params.put("clientIp", payOrder.getClientIp());
        if(!StringUtils.equals(null,payOrder.getDevice())&&payOrder.getDevice().length()>0){
            params.put("device", payOrder.getDevice());
        }
        params.put("returnUrl", payOrder.getReturnUrl());
        params.put("notifyUrl", payConfig.getNotifyUrl(getChannelName()));
        if(!StringUtils.equals(null,payOrder.getSubject())&&payOrder.getSubject().length()>0){
            params.put("subject", payOrder.getSubject());
        }
        if(!StringUtils.equals(null,payOrder.getBody())&&payOrder.getBody().length()>0){
            params.put("body", payOrder.getBody());
        }
        if(!StringUtils.equals(null,payOrder.getParam1())&&payOrder.getParam1().length()>0){
            params.put("param1", payOrder.getParam1());
        }
        if(!StringUtils.equals(null,payOrder.getParam2())&&payOrder.getParam2().length()>0){
            params.put("param2", payOrder.getParam2());
        }
        if(!StringUtils.equals(null,payOrder.getExtra())&&payOrder.getExtra().length()>0){
            params.put("extra", payOrder.getExtra());
        }
        params.put("sign",getSign(params,config.getPrivateKey()));

    }

    /**
     * 签名
     * @param parameters
     * @param key
     * @return
     */
    private String getSign( Map<String, Object> parameters, String key) {
        String signTxt = SignUtils.parameterText(parameters);
        _log.info("{}签名字符串：{}", logPrefix, signTxt);
        String sign = SignUtils.MD5.createSign(signTxt, "&key="+key, SignUtils.CHARSET_UTF8);
        return sign.toUpperCase();
    }

    /**
     * 构建支付url对象
     * @param retObj 返回的jsonobject对象
     * @param payOrder 请求支付订单的模型对象
     * @param channelPayUrl 渠道返回的支付地址
     * @return
     */
    protected JSONObject buildPayResultOfCodeURL(JSONObject retObj, PayOrder payOrder, String channelPayUrl) {
        // 设置支付订单ID
        retObj.put("payOrderId", payOrder.getPayOrderId());
        JSONObject payInfo = new JSONObject();
        payInfo.put("codeUrl", channelPayUrl); // 二维码支付链接
        payInfo.put("codeImgUrl", payConfig.getPayUrl() + "/qrcode_img_get?url=" + channelPayUrl + "&widht=200&height=200");
        payInfo.put("payMethod", PayConstant.PAY_METHOD_CODE_IMG);
        retObj.put("payParams", payInfo);
        retObj.put(PayConstant.RETURN_PARAM_RETCODE, PayConstant.RETURN_VALUE_SUCCESS);
        return retObj;
    }


    protected JSONObject buildPayResultOfForm(JSONObject retObj, PayOrder payOrder, String payForm) {
        // 设置支付订单ID
        retObj.put("payOrderId", payOrder.getPayOrderId());
        // 具体付款内容
        JSONObject payInfo = new JSONObject();
        payInfo.put("payUrl",payForm);
        payInfo.put("payMethod",PayConstant.PAY_METHOD_FORM_JUMP);
        retObj.put("payParams", payInfo);
        retObj.put(PayConstant.RETURN_PARAM_RETCODE, PayConstant.RETURN_VALUE_SUCCESS);
        return retObj;
    }
}
